<?php

namespace app\shop\controller;

use think\Controller;
use app\common\library\Email;

class Order extends Controller
{
    public function __construct()
    {
        parent::__construct();

        $this->BusinessModel = model('Business.Business');
        $this->OrderModel = model('Order.Order');
        $this->OrderProductModel = model('Order.Product');
        $this->RecordModel = model('Business.Record');
        $this->ProductModel = model('Product.Product');
        $this->CartModel = model('Product.Cart');
        $this->AddressModel = model('Business.Address');
        $this->ExpressqueryModel = model('Expressquery');
        $this->BackModel = model('Depot.Back.Back');
        $this->BackProductModel = model('Depot.Back.Product');
        $this->CouponReceiveModel = model('Coupon.Receive');
    }

    // 生成订单
    public function add()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $addrid = $this->request->param('addrid', 0, 'trim');
        $cartids = $this->request->param('cartids', 0, 'trim');
        $remark = $this->request->param('remark', 0, 'trim');
        $couponid = $this->request->param('couponid', 0, 'trim');
        $pay = $this->request->param('pay', 'money', 'trim');

        $business = $this->BusinessModel->find($busid);

        if (!$business) 
        {
            $this->error('该用户不存在');
            exit;
        }

        $address = $this->AddressModel->find($addrid);
        
        if (!$address) 
        {
            $this->error('收件地址不存在');
            exit;
        }

        $cart = $this->CartModel
            ->with(['product'])
            ->where('cart.id', 'in', $cartids)
            ->select();

        if (!$cart) 
        {
            $this->error('购物车商品不存在');
            exit;
        }
        
        //计算订单总价
        $total = array_column($cart, "total"); //提取数组中的某个字段，组成一个新数组
        $amount = array_sum($total); //对数组的求和

        //判断是否有使用优惠券
        $coupon = $this->CouponReceiveModel->with(['coupon'])->find($couponid);
        
        //优惠券在可用的情况下去优惠
        if($coupon && $coupon['status'] == '1')
        {
            $amount = bcmul($amount, $coupon['coupon']['rate'], 2);
        }

        // var_dump($coupon->toArray());
        // exit;

        //余额支付
        if($pay == "money")
        {
            // 判断用户余额
            $money = bcsub($business['money'], $amount, 2);

            if ($money < 0) 
            {
                $this->error('余额不足，请去充值');
                exit;
            }

            //开启事务
            $this->BusinessModel->startTrans();
            $this->OrderModel->startTrans();
            $this->OrderProductModel->startTrans();
            $this->RecordModel->startTrans();
            $this->ProductModel->startTrans();
            $this->CartModel->startTrans();
            $this->CouponReceiveModel->startTrans();

            // 生成订单号
            $code = build_code('SP');  // SP是订单号的前缀

            $OrderData = [
                'code' => $code,
                'busid' => $busid,
                'businessaddrid' => $addrid,
                'amount' => $amount,
                'remark' => $remark,
                'status' => '1', // 已支付
                'pay' => 'money', //余额支付
            ];

            //如果有使用优惠券就带上优惠券ID，给上优惠券的字段id
            if($coupon && $coupon['status'] == '1')
            {
                $OrderData['couponid'] = $couponid;
            } 

            // 插入订单表
            //订单表新增    校验器
            $OrderStatus = $this->OrderModel->save($OrderData);

            // 判断是否成插入订单
            // 注意：0也是也是会走进去，但是未必是报错，就是语句是ok的，但就是单纯没有插入进去
            if ($OrderStatus === FALSE)
            {
                $this->error($this->OrderModel->getError());
                exit;
            }

            // 插入订单商品表
            // 订单产品表的数据。因为到这一步就只是把订单插入进去，但是订单里的商品信息还是没有插入
            $OrderproductData = [];

            // 产品表数据
            $ProductData = [];

            // // 装购物车中不同类型的商品加起来以后的数量
            $stock = [];

            // 计算购物车的商品
            // 循环购物车
            // 看够不够减，把购物车中的商品类型相同的加到一起去。数据表当中，同一个用户，相同类型的商品加到一起去
            foreach($cart as $item)
            {
                if(isset($stock[$item['proid']])) //判断是否存在，存在往里走，不存在就给0
                {
                    // 这里做减法，用现有的库存，减去购物车的数量
                    $stock[$item['proid']] = bcadd($stock[$item['proid']], $item['nums']);
                }else
                {
                    $stock[$item['proid']] = $item['nums'];
                }

                //组装订单商品数据
                $OrderproductData[] = [
                    'orderid' => $this->OrderModel->id, //获取到上一步刚刚插入进去的记录的自增的ID
                    'busid' => $busid,
                    'proid' => $item['proid'],
                    'pronum' => $item['nums'],
                    'price' => $item['price'],
                    'total' => $item['total'],
                    'attrs' => $item['attrs']
                ];
            }

            //判断商品的库存是否充足
            foreach($stock as $key=>$item)
            {
                // 对商品的库存数量查询
                $pro = $this->ProductModel->field('id,stock,name')->where(['id' => $key])->find();
                
                $UpdateStock = bcsub($pro['stock'], $item);

                //库存不足
                if($UpdateStock < 0)
                {
                    $this->error($pro['name'] . '库存不足');
                    exit;
                }

                $ProductData[] = [
                    'id' => $pro['id'],
                    'stock' => $UpdateStock
                ];
            }

            // 订单产品表的新增  
            // saveAll()表示插入多条
            $OrderProductStatus = $this->OrderProductModel->saveAll($OrderproductData);

            if ($OrderProductStatus === FALSE)
            {
                $this->OrderModel->rollback();
                $this->error($this->OrderProductModel->getError());
                exit;
            }

            // 用户余额更新
            $BusinessStatus = $this->BusinessModel->where('id', $busid)->update(['money' => $money]);

            if ($BusinessStatus === FALSE) 
            {
                $this->OrderProductModel->rollback();
                $this->OrderModel->rollback();
                $this->error($this->BusinessModel->getError());
                exit;
            }

            //消费记录表
            $RecordData = [
                'total' => "-$amount",
                'busid' => $busid,
                'content' => "商城订单号：$code ---消费的金额：$amount 元",
            ];

            //插入语句
            $RecordStatus = $this->RecordModel->validate('common/Business/Record')->save($RecordData);

            if ($RecordStatus === FALSE) 
            {
                $this->BusinessModel->rollback();
                $this->OrderProductModel->rollback();
                $this->OrderModel->rollback();
                $this->error($this->RecordModel->getError());
                exit;
            }

            //判断是否有使用优惠券
            if($coupon && $coupon['status'] == '1')
            {
                $CouponData = [
                    'id' => $coupon['id'],
                    'status' => 0
                ];

                $CouponStatus = $this->CouponReceiveModel->isUpdate(true)->save($CouponData);

                if($CouponStatus === FALSE)
                {
                    $this->RecordModel->rollback();
                    $this->BusinessModel->rollback();
                    $this->OrderProductModel->rollback();
                    $this->OrderModel->rollback();
                    $this->error($this->CouponReceiveModel->getError());
                    exit;
                }
            }

            //产品表库存更新
            $ProductStatus = $this->ProductModel->isUpdate()->saveAll($ProductData);

            if ($ProductStatus === FALSE) 
            {
                $this->CouponReceiveModel->rollback();
                $this->RecordModel->rollback();
                $this->BusinessModel->rollback();
                $this->OrderProductModel->rollback();
                $this->OrderModel->rollback();
                $this->error($this->ProductModel->getError());
                exit;
            }

            // 删除购物车
            $CartStatus = $this->CartModel->destroy($cartids);

            if ($CartStatus === FALSE) 
            {
                $this->ProductModel->rollback();
                $this->CouponReceiveModel->rollback();
                $this->RecordModel->rollback();
                $this->BusinessModel->rollback();
                $this->OrderProductModel->rollback();
                $this->OrderModel->rollback();
                $this->error($this->CartModel->getError());
                exit;
            }
            

            if ($OrderStatus === FALSE || $OrderProductStatus === FALSE || $BusinessStatus === FALSE || $RecordStatus === FALSE || $ProductStatus === FALSE || $CartStatus === FALSE) {
                $this->CartModel->rollback();
                $this->ProductModel->rollback();
                $this->CouponReceiveModel->rollback();
                $this->RecordModel->rollback();
                $this->BusinessModel->rollback();
                $this->OrderProductModel->rollback();
                $this->OrderModel->rollback();
                $this->error('下单失败');
                exit;
            } else 
            {
                $this->OrderModel->commit();
                $this->OrderProductModel->commit();
                $this->BusinessModel->commit();
                $this->RecordModel->commit();
                $this->CouponReceiveModel->commit();
                $this->ProductModel->commit();
                $this->CartModel->commit();
                $this->success('下单成功', '/order/info', ['orderid' => $this->OrderModel->id]);
                exit;
            }
        }
    }

    // 订单列表
    public function index()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $status = $this->request->param('status', '', 'trim');
        $page = $this->request->param('page', 1, 'trim');
        $limit = 8;
        //偏移量
        $offset = ($page-1)*$limit;

        $business = $this->BusinessModel->find($busid);

        if (!$business) 
        {
            $this->error('该用户不存在');
            exit;
        }

        $where['busid'] = $busid;

        // 订单状态
        //  StatusActive.value,这里根据状态是几就查询几的状态，例如，是1就查询1时对应的状态
        // ['lt','0']：这里使用了数组来定义多个条件。lt 是 "less than" 的缩写，意味着我们要查询 status 字段值小于某个特定值的记录。'0' 是我们设定的比较值。
        if(!empty($status))
        {
            if($status > 0)
            {
                $where['status'] = $status;
            }else
            {
                $where['status'] = ['lt','0'];
            }
        }

        $list = $this->OrderModel
            ->where($where)
            ->order('createtime desc') //按时间降序进行查找
            ->limit($offset, $limit)  //每页的数量
            ->select();

        if($list)
        {
            //给订单添加一个自定义的下标 下标存放 订单商品信息(一个商品)
            foreach($list as &$item)
            {
                // 给find()查询一个订单商品，显示一个订单商品，如果想看其他，就点击商品详情
                $item['info'] = $this->OrderProductModel->with(['products'])->where(['orderid' => $item['id']])->find();
            }

            $this->success('返回订单列表', '', $list);
            exit;
        }else
        {
            $this->error('暂无更多数据');
            exit;
        }
    }

    // 订单详情
    public function info()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $orderid = $this->request->param('orderid', 0, 'trim');

        $business = $this->BusinessModel->find($busid);

        if (!$business) 
        {
            $this->error('该用户不存在');
            exit;
        }

        // 查询订单的记录
        $order = $this->OrderModel->find($orderid);

        if (!$order) 
        {
            $this->error('订单不存在');
            exit;
        }

        // 查找一条收货地址记录。 AddressModel 表中 id 字段等于 $order['businessaddrid'] 的记录
        $address = $this->AddressModel->where(['id' => $order['businessaddrid']])->find();

        if(!$address)
        {
            $this->error('收货地址不存在');
            exit;
        }

        //判断是否有使用优惠券
        $couponid = isset($order['couponid']) ? $order['couponid'] : 0;
        // 查询一条优惠券的记录。因为是每次只能用一张优惠券，所以一条。
        // with(['coupon'])表示连表查询的方法，查询使用的优惠券的减了多少钱
        $coupon = $this->CouponReceiveModel->with(['coupon'])->find($couponid);

        // 如果查到有使用优惠券的记录
        if($coupon)
        {

            // 这里可以打印出来优惠券的信息,然后拿数据
            // var_dump($coupon['coupon']->toArray());
          

            // 获取折扣率
            $rate = isset($coupon['coupon']['rate']) ? $coupon['coupon']['rate'] : 1;

            // 获取使用的是哪一张优惠券
            $coupon_name = isset($coupon['coupon']['title']) ? $coupon['coupon']['title'] : '优惠活动';
            
            // var_dump($order->toArray());


            //原价总的价格
            $total = $this->OrderProductModel->where(['orderid' => $orderid])->sum('total');

            //订单优惠后的价格
            $amount = $order['amount'];

            //优惠的金额数
            // bcsub()表示高精度浮点数相减
            $coupon_amount = bcsub($total, $amount);

            // 根据优惠金额去判断是否使用了优惠券
            if($coupon_amount > 0)
            {
                $order['coupon_amount'] = "-￥$coupon_amount ($coupon_name)";
            }else
            {
                $order['coupon_amount'] = '暂无优惠金额';
            }
        }else  // 如果没有优惠券
        {
            
            $order['coupon_amount'] = '暂无优惠金额';
        }

        // 查找所有的订单商品
        // with(['products'])这是一个关联查询方法
        $product = $this->OrderProductModel->with(['products'])->where(['orderid' => $orderid])->select();

        $data = [
            'order' => $order,
            'product' => $product,
            'address' => $address,
        ];

        $this->success('订单详情', '', $data);
        exit;
    }

    // 确认收货
    public function confirm()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $orderid = $this->request->param('orderid', 0, 'trim');

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('该手机号用户不存在');
            exit;
        }

        $orderinfo = $this->OrderModel->with('address')->find($orderid);

        if (!$orderinfo) {
            $this->error('订单不存在');
            exit;
        }

        $result = $this->OrderModel->where('id', $orderid)->update(['status' => '3']);

        if ($result) {
            $this->success('确认收货成功');
        } else {
            $this->error($this->OrderModel->getError());
        }
    }

    // 物流详情
    public function express()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $orderid = $this->request->param('orderid', 0, 'trim');
        $backid = $this->request->param('backid', 0, 'trim');

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('该手机号用户不存在');
            exit;
        }

        // 物流单号
        $expresscode = '';

        // 订单物流
        if ($orderid > 0) {
            $orderinfo = $this->OrderModel->with('address')->find($orderid);

            if (!$orderinfo) {
                $this->error('订单不存在');
                exit;
            }

            $expresscode = $orderinfo['expresscode'];
        }

        // 退货物流
        if ($backid > 0) {
            $backinfo = $this->BackModel->find($backid);

            if (!$backinfo) {
                $this->error('退货订单不存在');
                exit;
            }

            $expresscode = $backinfo['expresscode'];
        }


        if (empty($expresscode)) {
            $this->error('暂无物流信息');
            exit;
        }

        // 物流接口地址
        $url = "http://wdexpress.market.alicloudapi.com/gxali";

        $params = [
            'n' => $expresscode,
        ];

        $paramsString = http_build_query($params);

        $appcode = "填写自己的AppCode"; //开通服务后 买家中心-查看AppCode
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);

        // 判断是否有物流缓存
        if (cache($expresscode)) {
            $this->success('', '', cache($expresscode));
        } else {
            // 调取物流接口
            $expressinfo = HttpRequest($url, $paramsString, 0, $headers);

            $result = json_decode($expressinfo, true);

            if ($result['Success'] == true) {
                // 设置路由缓存
                cache($expresscode, $result['Traces']);
                $this->success('', '', $result['Traces']);
            } else {
                $this->error($result['Reason']);
            }
        }
    }

    // 申请退款
    public function apply()
    {
        // 分别接收用户id，订单id，退款原因
        $busid = $this->request->param('busid', 0, 'trim');
        $orderid = $this->request->param('orderid', 0, 'trim');
        $remark = $this->request->param('remark', '', 'trim');

        // 先判断用户是否存在
        $business = $this->BusinessModel->find($busid);

        if (!$business) 
        {
            $this->error('该手机号用户不存在');
            exit;
        }

        // 判断订单是否存在
        $order = $this->OrderModel->find($orderid);

        if (!$order) 
        {
            $this->error('订单不存在');
            exit;
        }

        $OrderData = [
            'id' => $orderid, //更新语句所以带上id
            'business_reason' => $remark, //退款原因
        ];

        //已支付，仅退款
        if($order['status'] == "1")
        {
            $OrderData['status'] = '-1';
        }else if($order['status'] == "2")
        {
            //已发货，申请退货退款
            $OrderData['status'] = '-2';
        }

        // 更新语句
        $result = $this->OrderModel->isUpdate(true)->save($OrderData);

        // 申请退款失败
        if ($result === FALSE) 
        {
            $this->error('申请失败');
            exit;
        } else 
        {
            $this->success('申请成功，待商家审核');
            exit;
        }
    }

    // 退货详情
    public function refundgoodsinfo()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('该手机号用户不存在');
            exit;
        }

        // 物流信息
        $expresslist = $this->ExpressqueryModel->field('id as value,name as text')->select();

        $address = $this->AddressModel->select();

        $addresslist = [];

        foreach ($address as $item) {
            $addresslist[] = [
                'value' => $item['id'],
                'text' => $item['consignee'] . '-' . $item['mobile'] . '-' . $item['region_text'] . $item['address'],
            ];
        }

        $data = [
            'expresslist' => $expresslist,
            'addresslist' => $addresslist,
        ];

        $this->success('', '', $data);
    }

    // 退货物流
    public function refundgoods()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $businessaddrid = $this->request->param('businessaddrid', 0, 'trim');
        $expresscode = $this->request->param('expresscode', '', 'trim');
        $expressid = $this->request->param('expressid', 0, 'trim');
        $orderid = $this->request->param('orderid', 0, 'trim');

        $business = $this->BusinessModel->find($busid);
        if (!$business) {
            $this->error('该手机号用户不存在');
            exit;
        }

        $addressinfo = $this->AddressModel->find($businessaddrid);
        if (!$addressinfo) {
            $this->error('收件地址不存在');
            exit;
        }

        $orderinfo = $this->OrderModel->find($orderid);

        if (!$orderinfo) {
            $this->error('订单不存在');
            exit;
        }

        $OrderProductlist = $this->OrderProductModel->where('orderid', $orderid)->select();

        if (!$OrderProductlist) {
            $this->error('订单商品不存在');
            exit;
        }

        /*
            退货表： 新增  验证器
            退货商品表： 新增 验证器
        */

        $this->BackModel->startTrans();
        $this->BackProductModel->startTrans();

        $BackData = [
            'code' => build_code('BP'),
            'ordercode' => $orderinfo['code'],
            'busid' => $busid,
            'contact' => $addressinfo['consignee'],
            'phone' => $addressinfo['mobile'],
            'address' => $addressinfo['address'],
            'province' => $addressinfo['province'],
            'city' => $addressinfo['city'],
            'district' => $addressinfo['district'],
            'amount' => $orderinfo['amount'],
            'expressid' => $expressid,
            'expresscode' => $expresscode,
            'status' => '1'
        ];

        $BackStatus = $this->BackModel->save($BackData);

        if ($BackStatus === false) {
            $this->error($this->BackModel->getError());
            exit;
        }

        $ProductData = [];

        foreach ($OrderProductlist as $item) {
            $ProductData[] = [
                'backid' =>  $this->BackModel->id,
                'proid' => $item['proid'],
                'nums' => $item['pronum'],
                'price' => $item['price'],
                'total' => $item['total'],
            ];
        }

        // 循环校验数据
        $BackProductStatus = $this->BackProductModel->saveAll($ProductData);

        if ($BackProductStatus === false) {
            $this->BackModel->rollback();
            $this->error($this->BackProductModel->getError());
            exit;
        }

        if ($BackProductStatus === false || $BackStatus === false) {
            $this->BackModel->rollback();
            $this->BackProductModel->rollback();
            $this->error('退货物流失败');
            exit;
        } else {
            $this->BackModel->commit();
            $this->BackProductModel->commit();
            $this->success('退货物流成功');
            exit;
        }
    }

    // 商品评价
    public function rate()
    {
        $busid = $this->request->param('busid', 0, 'trim');
        $orderid = $this->request->param('orderid', 0, 'trim');
        $orderproid = $this->request->param('orderproid', 0, 'trim');
        $rate = $this->request->param('rate', 0, 'trim');
        $comment = $this->request->param('comment', '', 'trim');

        $business = $this->BusinessModel->find($busid);
        if (!$business) {
            $this->error('该手机号用户不存在');
            exit;
        }

        $orderinfo = $this->OrderModel->find($orderid);

        if (!$orderinfo) {
            $this->error('订单不存在');
            exit;
        }

        $OrderProductlist = $this->OrderProductModel->where('orderid', $orderid)->select();

        if (!$OrderProductlist) {
            $this->error('订单商品不存在');
            exit;
        }

        //评价状态
        $rate_status = false;

        foreach ($OrderProductlist as $item) {
            if ($item['rate'] == NULL && $item['id'] == $orderproid) {
                $rate_status = true;
            } else {
                $rate_status = false;
            }
        }
        // 订单商品单个评价  开启事务， 订单表：更新订单状态，更改为已完成，订单产品表：更新评论内容
        if ($rate_status) {

            $OrderProductData = [
                'id' => $orderproid,
                'busid' => $busid,
                'rate' => $rate,
                'comment' => $comment
            ];

            if (isset($_FILES[$orderproid])) {
                $success = build_uploads($orderproid);
                if ($success['result']) {
                    $OrderProductData['proimg'] = $success['data'];
                } else {
                    $this->error($success['msg']);
                    exit;
                }
            }

            // 开启事务
            $this->OrderModel->startTrans();
            $this->OrderProductModel->startTrans();

            $OrderStatus = $this->OrderModel->where('id', $orderid)->update(['status' => '4']);
            if ($OrderStatus === false) {
                $this->error($this->OrderModel->getError());
                exit;
            }

            $OrderProductStatus = $this->OrderProductModel->isUpdate()->save($OrderProductData);

            if ($OrderProductStatus === false) {
                $this->OrderModel->rollback();
                $this->error($this->OrderProductModel->getError());
                exit;
            }

            if ($OrderStatus === false || $OrderProductStatus === false) {
                $this->OrderModel->rollback();
                $this->OrderProductModel->rollback();
                $this->error('评价失败');
            } else {
                $this->OrderModel->commit();
                $this->OrderProductModel->commit();
                $this->success('评价成功');
            }
        }
        // 订单商品多个评价
        else {
            $OrderProductData = [
                'id' => $orderproid,
                'busid' => $busid,
                'rate' => $rate,
                'comment' => $comment
            ];
            
            if (isset($_FILES[$orderproid])) {
                $success = build_uploads($orderproid);
                if ($success['result']) {
                    $OrderProductData['proimg'] = $success['data'];
                } else {
                    $this->error($success['msg']);
                    exit;
                }
            }

            $result = $this->OrderProductModel->isUpdate()->save($OrderProductData);

            if($result === false)
            {
                $this->error('评价失败');
            } else {
                $this->success('评价成功');
            }
        }
    }
}
